\documentclass[a4paper,10pt]{article}

\usepackage{graphicx}
\usepackage{amsmath}
\usepackage[latin1]{inputenc}
\usepackage[spanish]{babel}

\title{ \textbf{ 6620. Organizaci\'on de Computadoras\\
Trabajo Pr\'actico 1: \\
Conjunto de instrucciones MIPS}}

\author{	Gonz\'alez, Juan Manuel, \textit{Padr\'on Nro. 79.979} \\
            	\texttt{ juanmg0511@gmail.com } \\[2.5ex]
            	Kux, Daniel, \textit{Padr\'on Nro. 80.560} \\
            	\texttt{ danielkux@gmail.com } \\[2.5ex]
		Morales, Nahuel, \textit{Padr\'on Nro. 89.918} \\
		\texttt{ nahuel.leandro@gmail.com } \\[2.5ex]
            	\normalsize{1er. Cuatrimestre de 2013} \\
            	\normalsize{66.20 Organizaci\'on de Computadoras  $-$ Pr\'atica Jueves} \\
            	\normalsize{Facultad de Ingenier\'ia, Universidad de Buenos Aires} \\
				\\
            	\normalsize{Fecha de entrega: 02/05/2013} \\
            	\normalsize{Fecha de re-entrega: 16/05/2013} \\
       }

\date{}

\begin{document}
\maketitle
\thispagestyle{empty}  % quita el numero en la primer pagina

\begin{abstract}
El presente trabajo pr\'actico tiene como objetivo familiarizarse con el conjunto de instrucciones MIPS32 y el concepto de ABI, desarrollando para ello una versi\'on en lenguaje assembly del algoritmo de ordenamiento \textit{Shellsort}. Para ello, se partir\'a primero de una implementaci\'on en lenguaje C de un programa que permite ordenar palabras, tanto mediante el mencionado algoritmo como adem\'as tambi\'en el de \textit{Bubblesort}. Este programa ser\'a utilizado para hacer diversos c\'alculos de performance, mediante el uso de la utilidad \textit{time}.
\end{abstract}

\pagebreak
\renewcommand{\contentsname}{Contenidos}
\tableofcontents
\setcounter{page}{2}
\pagenumbering{roman}
\pagebreak

\setcounter{page}{1}
\pagenumbering{arabic}
\section{Introducci\'on}
El presente trabajo tiene como objetivo familiarizarse con el conjunto de instrucciones MIPS32 y el concepto de ABI. Se utilizar\'a el programa GXemul para simular un entorno de desarrollo en una m\'aquina MIPS (corriendo una versi\'on del sistema operativo NetBSD).\\
Se deben implementar en lenguaje C dos algoritmos de ordenamiento: \textit{Bubblesort}[7] y \textit{Shellsort}[8], que deben ordenar palabras en un archivo. Una vez implementados, se proceder\'a a realizar mediciones para evaluar el desempen\~no relativo entre ambas implementaciones, utilizando el programa \textit{time}[9].\\
Asimismo, se deber\'a proveer una versi\'on en assembler MIPS32 del algoritmo de \textit{Shellsort}, y comparar su desempe\~no con el de la versi\'on en C.

\section{Programa a implementar}
El problema a resolver consiste en implementar un programa que realice ordenamiento o \textit{sorting}, a fin de ordenar las palabras de un texto, utilizando los algorimos de \textit{Bubblesort} o \textit{Shellsort}, seg\'un elija el usuario.\\

El programa debe leer los datos de entrada desde \textit{stdin} o bien desde uno o m\'as archivos. La salida del programa debe imprimirse por \textit{stdout}, mientras que los errores deben imprimirse por \textit{stderr}. El algoritmo de ordenamiento puede seleccionarse mediante las opciones \textbf{-m} o \textbf{-s} para \textit{Bubblesort} o \textit{Mergesort} respectivamente.\\

La sintaxis de llamada al programa es la siguiente:

{\footnotesize \begin{verbatim}
      tp1 [OPTIONS] [file...]
      -h, --help	 display this help and exit.
      -V, --version	 display version information and exit.
      -m, --bubble	 use bubblesort algorithm.
      -s, --sel	 use shellsort algorithm.
\end{verbatim}}

\section{Consideraciones sobre el desarrollo}
A continuaci\'on se detallan las consideraciones tenidas en cuenta para el desarrollo del trabajo pr\'actico. Hemos decidido separar las que surgen del Dise\~no de las que surgen en la implementaci\'on.

\subsection{Consideraciones de Dise\~no}
El programa desarrollado para resolver el presente trabajo pr\'actico consta a grandes rasgos de un int\'erprete de l\'inea de comandos, la rutina que lee los datos de entrada desde \textit{stdin}, una estructura de datos dise\~nada para almacenarlos, la funci\'on encargada de efectuar el ordenamiento y finalmente la funci\'on que imprime la salida del programa.\\
Dado que las funciones implementadas no son de gran complejidad, no se consider\'o necesario separar el proyecto en varios archivos, salvo por los algoritmos de ordenamiento, que s\'i fueron implmentados por separado para facilitar la integraci\'on con la versi\'on MIPS32 de \textit{Shellsort}. A continuaci\'on se presenta la lista de archivos que componen el proyecto:\\
\\
\begin{tabular}{|l|l|}
\hline
Archivo & Descripci\'on \\ \hline
tp1.c & Funci\'on main, int\'erprete de l\'inea de comandos y funciones de E/S. \\
bubblesort.h & Encabezado correspondiente a 'bubblesort.c'. \\
bubblesort.c & Implementaci\'on de \textit{Bubblesort}. \\
shellsort.h & Encabezado correspondiente a 'shellsort.c'. \\
shellsort.c & Implementaci\'on de \textit{Shellsort}. \\
\hline
\end{tabular}\\
\\

Dado que la aplicaci\'on puede tomar par\'ametros variables de ejecuci\'on o adoptar valores por defecto, se realiz\'o un an\'alisis completo de todas las opciones que un usuario puede ingresar, aceptando aquellas que fueren v\'alidas y rechazando las que no, con el consiguiente mensaje de error que el usuario visualizar\'a en pantalla. En caso de no ser especificado un algoritmo de ordenamiento, el programa asumir\'a la opci\'on \textbf{-s}, correspondiente a \textit{Shellsort}. Esta decisi\'on se encuentra fundamentada en la performance del algoritmo frente a la otra opci\'on disponible.\\

A grandes rasgos, la soluci\'on intenta leer el \textit{input} de datos que es especificado por el usuario. Puede constar de varios archivos o directamente ser la entrada est\'andar. De no resultar satisfactoria esta operaci\'on, ya sea porque el archivo no existe o se produjere un fallo en el disco en el momento de la lectura, se retorna de inmediato el correspondiente c\'odigo de error. Si pueden tomarse los datos de entrada, el programa procede a su almacenamiento en un estructura del tipo \textit{char**}, separando las palabras. El criterio definido para esta operaci\'on es el de tomar como delimitador de palabra cualquier carcter no alfanum\'erico. En caso de tratarse de varios archivos, todas las palabras son almacenadas de corrido en una \'unica estructura, siguiendo el orden en que fueron introducidos los archivos de origen en la llamada al programa. La memoria que ocupa esta estructura es reservada memoria en forma d\'inamica, a medida que es requerida. Como \'ultimo paso, una vez que se cuenta con los datos cargados, se continua la ejecuci\'on realizando el ordenamiento indicado por el usuario, volcando el resultado de dicha operaci\'on por la salida est\'andar o \textit{stdout}.\\

Por otro lado, se dise\~n\'o el programa de modo que todas las salidas por \textit{stdout} o \textit{stderr} se encuentren en la funci\'on main o en funciones dedicadas a ese prop\'osito. En el caso del mensaje de ayuda y el de versi\'on del programa, se codificaron dos funciones espec\'ificas, mientras que los mensajes de error son mostrados dentro de las respectivas funciones.\\

La ejecuci\'on del programa se interrumpe ante cualquier error o situaci\'on an\'omala, mostrando al usuario un mensaje afin. Los c\'odigos 0 y 1 son utilizados para la devoluci\'on al SO del resultado de la ejecuci\'on, siendo:\\
\\
0: Ejecuci\'on sin problemas.\\
1: Error de ejecuci\'on.\\
\\
El procesamiento e interpretaci\'on de los comandos ingresados desde la consola es manejado mediante la biblioteca 'getopt', evitando as\'i la implementaci\'on de un parser para este fin. Dado que el enunciado presenta un mensaje de ayuda en idioma ingl\'es, se han codificado todas las salidas en este idioma. Asimismo, los mensajes de error fueron formateados para imitar la salida de 'getopt', con el fin de presentar los errores en forma consistente.\\

\subsection{Consideraciones de Implementaci\'on}

Cabe destacar que para implementar el trabajo pr\'actico se parti\'o de la totalidad del programa implementado en lenguage C (se ha respetado el est\'andar ANSI) y luego se procedi\'o a traducir a assembly de MIPS el c\'odigo final.\\

Las principales funciones en nuestra implementaci\'on son las siguientes:\\

\textit{\underline{validateFileAndReadWords}}
Esta funci\'on se encarga de tomar los archivos de entrada, validar su existencia y validez, abrirlos y finalmente llamar a la funci\'on que va guardando su contenido. Los archivos se van abriendo dentro de un bucle \textit{for}, y el programa se detiene en caso de producirse un error.\\

\textit{\underline{readFromStdinAndReadWords}}
Esta funci\'on tiene como objetivo tomar la entrada enviada por el usuario en caso de ser seleccionada la entrada est\'andar o \textit{stdin}, y luego llamar a la funci\'on que guarda el contenido ingresado por el usuario.\\

\textit{\underline{readWords}}
Esta funci\'on es la encargada de separar las palabras contenidas en los textos de entrada, reservar la memoria necesaria para almacenarlas y guardar cada una de ellas en la estructura destinada a tal fin.\\

\textit{\underline{bubblesort}}
Se trata de la implmentaci\'on de algoritmo de ordenamiento \textit{Bubblesort}.\\

\textit{\underline{shellsort}}
Se trata de la implmentaci\'on de algoritmo de ordenamiento \textit{Shellsort}.

\subsubsection{Portabilidad de la soluci\'on}
El programa est\'a dise\~nado para poder ser ejecutado en diferentes plataformas, como por ejemplo NetBSD (PMAX) y la versi\'on de Linux usada para correr el simulador, GNU/Linux (i686). El haber codificado el proyecto en ANSI C garantiza que pueda ser compilado en ambas plataformas sin problemas, dotando al programa de un grado m\'inimo de portabilidad.\\
Por otro lado, se destaca que se entrega junto con el presente informe dos versiones del c\'odigo fuente para el \textit{Shellsort}, una en formato C y la otra en c\'odigo assembly MIPS.

\subsubsection{Generaci\'on de ejecutables}
Para generar el ejecutable del programa utilizando la versi\'on implementada en lenguaje C, debe correrse la siguiente sentencia en una terminal:
\begin{verbatim}
$ gcc -Wall -o tp1 tp1.c bubblesort.c shellsort.c
\end{verbatim}

Para utilizar el c\'odigo assembly MIPS32, debe ejecutarse lo siguiente:
\begin{verbatim}
$ gcc -Wall -o tp1 tp1.c bubblesort.c shellsort.S
\end{verbatim}

N\'otese que para ambos casos se han activado todos los mensajes de 'Warning' (-Wall).

\subsubsection{Descripci\'on del algoritmo de la funci\'on \textit{shellsort}}
Para la implmentaci\'on en C se tom\'o como referencia la versi\'on en \textit{pseudoc\'odigo} presente en [8]. A continuaci\'on se muestra el c\'odigo final, adaptado para respetar el prototipo propuesto por la c\'atera en el enunciado:

{\footnotesize \begin{verbatim}
      #define SEQUENCESIZE 8

      void shellsort (char **words, int arraysize) {

      int i, j, k, gap = 0;
      int a[SEQUENCESIZE] = {701, 301, 132, 57, 23, 10, 4, 1};
      char *x = NULL;

      for(k=0; k < SEQUENCESIZE; k++) {
        gap = a[k];
        for(i=gap; i < arraysize; ++i) {
          x = words[i];
          for(j=i-gap; ((j >= 0) && (strcasecmp(words[j],x) > 0)); j=j-gap)
            words[j+gap] = words[j];
          words[j+gap] = x;
          }
        }
      }
\end{verbatim}}

El planteo de la soluci\'on en MIPS32 comenz\'o mediante el an\'alisis de la implementaci\'on previamente obtenida en C, dando como resultado el stack de la funci\'on y un lineamiento de las estructuras de control a utilizar. Con esto, se procedi\'o a efectuar un proceso de traducci\'on del c\'odigo de alto nivel al assembly, por etapas:

\begin{enumerate}
\item 
Manejo de la creaci\'on y destrucci\'on del \textit{stack} de la funci\'on.
\item
Implementaci\'on del bucle externo, controlado por la variable \textit{k}.
\item
Implementaci\'on del bucle intermedio, controlado por la variable \textit{i}.
\item
Implementaci\'on del bucle interno, controlado por la variable \textit{j}.
\item
Asignaci\'on del valor de la variable \textit{gap}.
\item
Asignaci\'on de \textit{x} e intercambio de las posiciones en \textit{words}.
\item
Llamada a la funci\'on \textit{strcasecmp}.
\end{enumerate}

Al ser finalizado cada uno de \'estos puntos, se probaba el programa, para asegurar un correcto funcionamiento y evitar los inconvenientes derivados de realizar las primeras pruebas sobre el desarrollo completo.\\

\subsubsection{Diagrama del \textit{stack} de la funci\'on \textit{shellsort}}
A continuaci\'on se muestra el diagrama del \textit{stack} para implementaci\'on en MIPS32 de la funci\'on \textit{shellsort}:

\begin{center}
\includegraphics[scale=0.70]{stack_shellsort.png}
\end{center}

\pagebreak

\section{Corridas de prueba}
En esta secci\'on se presentan algunas de las distintas corridas que se realizaron para probar el funcionamiento del trabajo pr\'actico.\\
\\
En primer lugar se gener\'o el ejecutable y se ejecut\'o una prueba trivial:
\begin{center}
\includegraphics[scale=0.60]{1.png}
\end{center}

Una vez hecho esto, se mostr\'o el mensaje de ayuda, y luego se imprimi\'o la versi\'on del programa:
\begin{center}
\includegraphics[scale=0.60]{2.png}
\end{center}

Luego, se ejecut\'o la prueba provista por la c\'atedra en el enunciado del trabajo pr\'actico:
\begin{center}
\includegraphics[scale=0.60]{3.png}
\end{center}

Finalmente, se presenta un ejemplo m\'as mostrando alguna de las salidas posibles, obtenida para casos en los que se toma entrada por \textit{stdin} en modo interactivo:\\
\begin{center}
\includegraphics[scale=0.60]{4.png}
\end{center}

Por otro lado, adem\'as de las pruebas mostradas, tambi\'en fue necesario ordenar con ambos algoritmos los archivos provistos por la c\'atedra: ``alice.txt'', ``beowulf.txt'', ``cyclopedia.txt'' y ``elquijote.txt''. Estos textos fueron ordenados mediante \textit{bubblesort} y ambas implementaciones de \textit{shellsort}. Para este \'ultimo caso, se control\'o mediante el comando diff que las salidas fueran coincidentes. 

\section{Mediciones} 
Se compar\'o la performance de cada uno de los algoritmos de ordenamiento realizando pruebas con el comando \textit{time}. Se tom\'o el tiempo insumido por cada uno de los algoritmos tomando los archivos provisto por la c\'atedra junto con el enunciado. Estos son:

\begin{enumerate}
\item 
alice.txt, 177KB
\item
beowulf.txt, 225KB
\item
cyclopedia.txt, 659KB
\item
elquijote.txt, 2147KB
\end{enumerate}

Los resultados obtenidos se resumen en la siguiente tabla. Los tama\~nos de las muestras se obtuvieron mediante el comando \textit{wc}:
\begin{center}
\includegraphics[scale=0.50]{tablatime.png}
\end{center}

En los dos casos que se visualiza un tiempo mayor a 3600 segundos, el proceso fue abortado ya que se ejecu\'o la prueba haciendo uso del comando \textit{timeout} configurado a una hora. Esto se decidi\'o por recomendaci\'on de la c\'atedra, ya que los tiempos de procesamiento del \textit{Bubblesort} para estos archivos resultaba excesivo.\\

\pagebreak

Al computar los tiempos presentados arriba, y con el fin de realizar una medici\'on cuantitativa de la mejora de performance para cada implementaci\'on, se calcularon los \textit{speedups}, present\'andose los resultados en la siguiente tabla:
\begin{center}
\includegraphics[scale=0.50]{tablasu.png}
\end{center}

Se realizaron gr\'aficos comparativos con curvas que representan cada algoritmo, representando el tiempo insumido (segundos) en relaci\'on con el tama\~no del archivo de entrada (palabras), el \textit{speedup} obtenido entre \textit{Bubblesort} y \textit{Shellsort} y finalmente \textit{speedup} obtenido entre las dos implmementaciones de \textit{Shellsort}.\\

Este gr\'afico resume para ambos algoritmos el tiempo de proceso en funci\'on del tama\~no del archivo::
\begin{center}
\includegraphics[scale=0.45]{graficotvp.png}
\end{center}

\pagebreak

Este gr\'afico representa el \textit{speedup} obtenido entre \textit{Bubblesort} y \textit{Shellsort}:
\begin{center}
\includegraphics[scale=0.42]{graficosubvs.png}
\end{center}

Finalmente, este gr\'afico representa el \textit{speedup} obtenido entre las dos implementaciones de \textit{Shellsort}:
\begin{center}
\includegraphics[scale=0.42]{graficosus.png}
\end{center}

Luego de correr los distintos m\'etodos de ordenamiento (\textit{Bubblesort}, \textit{Shellsort en C}, \textit{Shellsort en Assembly}) para los distintos archivos, se pudo notar las diferencias entre cada uno de los algoritmos. Lo m\'as destacable al respecto es la diferencia en tiempos de ejecuci\'on entre los algoritmos de \textit{Bubblesort} y \textit{Shellsort}, lo que demuestra la ineficiencia del primer m\'etodo. Estos resultados son consistentes con el orden de cada uno de estos algoritmos, y en el caso del \textit{Bubblesort} fue tal el tiempo que se insumi\'o ordenando los casos m\'as grandes, que el ``timeout'' estipulado en una hora cort\'o el proceso. Esto contrasta con la eficiencia del \textit{Shellsort}, que finaliz\'o todas las pruebas en menos de 3 minutos. Se destaca en relaci\'on a esto el alto valor de \textit{speedup} obtenido entre ambos algorimos de sort, para los casos en los cuales fue posible el c\'alculo.\\
\\
Otro resultado valioso fue el obtenido por las diferencias entre los tiempos de ejecuci\'on de los distintos algoritmos de \textit{Shellsort}, el implementado en C y el implementado en assembly. Tal como esper\'abamos, el algoritmo implementado en assembly es mas r\'apido que el implementado en C, esto es consecuencia de que la versi\'on en C resulta mas compleja al ser traducida al assembly por el compilador. En cambio, al implementar el c\'odigo de forma manual en assembly, los algoritmos y la cantidad de instrucciones se pueden optimizar, logrando mejoras en la performance.\\

\pagebreak

\section{Conclusiones}
A modo de conclusi\'on, nos es inmediato resaltar la dificultad que nos ha presentado el programa motivo de este informe. No solo la adaptaci\'on requerida para trabajar con un lenguaje ensamblador y el conjunto de instrucciones del procesador, sino la incorporaci\'on del m\'etodo de programaci\'on que un proyecto de este tipo conlleva.\\

La resoluci\'on del TP nos permiti\'o familiarizarnos a fondo con el conjunto de instrucciones de MIPS32, as\'i como tambi\'en el concepto de ABI. La comprensi\'on de este \'ultimo concepto fue fundamental para el desarrollo de la soluci\'on, ya que en m\'as de una oportunidad nuestro c\'odigo assembly fall\'o por estar mal diagramando el \textit{stack} de la funci\'on a desarrollar. El partir de una implementaci\'on previa en C, as\'i como tambi\'en contar con el prototipo de la funci\'on, nos impuso la necesidad de investigar formas de resolver la traducci\'on del c\'odigo C utilizando instrucciones que nos eran desconocidas.\\  

Asimismo, consideramos acertada la decisi\'on de haber realizado el desarrollo de la funci\'on involucrada en la soluci\'on en etapas, con pruebas intermedias como se describe anteriormente, debido a nuestra falta de experiencia con MIPS32. Lo mismo puede afirmarse de haber tomado como gu\'ia la implementaci\'on en lenguaje C.\\

Las mediciones realizadas permitieron establecer que ambos algorimos se comportaron como era esperado, observ\'andose en los gr\'aficos c\'omo la curva del tiempo insumido por el \textit{Bubblesort} es casi exponencial, mientras que la curva del \textit{Shellsort} es mucho m\'as estable. Esto trae aparejado valores de \textit{speedup} muy altos cuando se comparan ambos algoritmos.\\
En cuanto a la implementaci\'on de \textit{Shellsort} en MIPS32 y su comparaci\'on con la versi\'on en C, se destaca que existe una ganancia de performance al trabajar en bajo nivel, que tiende a aumentar con muestras mas grandes, lo pone en evidencia la ventaja de optimizar los algorimos utilizando assembly.\\

Finalmente, en base a los resultados obtenidos y el tiempo que demand\'o el desarrollo de la tarea, en comparaci\'on con el esfuerzo requerido para resolver el mismo problema en lenguaje C, creemos que en el caso de un sistema real, seguramente mucho mas complejo, inexorablemente habr\'a que evaluar la relaci\'on costo/beneficio de realizar una implmentaci\'on de este tipo.
\pagebreak

\appendix
\section{Correcciones respecto a la primer entrega}
Se incluye en esta secci\'on un listado con las correcciones realizadas sobre la primer entrega de este trabajo pr\'actico:

\begin{enumerate}
\item 
Se modific\'o la l\'inea 94 del archivo ``tp1.c''. Se cambi\'o la llamada a \textit{isalpha} para evitar el \textit{warning} emitido por GCC al hacer el build de la soluci\'on.
\item
Se modific\'o el archivo ``shellsort.S''. Se eliminaron las l\'ineas que s\'olo conten\'ian comentarios (fueron reposicionados) para permitir la generaci\'on del ejecutable sin errores al utilizar el flag de GCC ``-{}-ansi''.
\item
Hechas las correcciones de los dos puntos anteriores, se verific\'o que el build del programa finalizara sin \textit{warnings} en ambos ambientes. Se adjunta captura del build realizado en \textit{gxemul}:
\begin{center}
\includegraphics[scale=0.50]{5.png}
\end{center}
\item
Se corrigieron las tablas y gr\'aficos de la secc\'on ``Mediciones''. No se realiz\'o el c\'alculo de \textit{speedup} para los 2 casos en que el \textit{Bubblesort} termin\'o por \textit{timeout}. Se eliminaron esos resultados del gr\'afico en que se visualiza el \textit{speedup} obtenido entre \textit{Bubblesort} y \textit{Shellsort}.
\item
Se incluyeron en el informe la tabla de contenidos y el presente ap\'endice enumerando las correcciones realizadas.
\end{enumerate}

\pagebreak

\begin{thebibliography}{99}

\bibitem{GXEMUL} GXemul, http://gxemul.sourceforge.net/

\bibitem{LIBROC} Kernighan, Brian W. / Ritchie, Dennis M. \underline{El Lenguaje De Prorgamaci\'on C}. Segunda Edici\'on, PRENTICE-HALL HISPANOAMERICANA SA, 1991.

\bibitem{LIBROC2} Schildt, Herbert. \underline{C: The complete Reference}. Fourth Edition. McGraw-Hill Osborne Media, 2000.

\bibitem{PATHEN} Patterson / Hennesy. \underline{Computer Organization and Design; The Hardware-Software Interface}. Second Edition. Morgan Kaufman, 1997.

\bibitem{MIPSINTRO} S/R autor. \underline{MIPS32\texttrademark Architecture For Programmers Volume I}. Revision 0.95. MIPS Technologies Inc, 2001.

\bibitem{MIPSABI} S/R autor. \underline{System V ABI, MIPS RISC processor supplement}. Third Edition. Santa Cruz Operations, Inc, S/R A\~NO.

\bibitem{BUBBLE} Bubble-sort, http://en.wikipedia.org/wiki/Bubble\_sort/

\bibitem{SHELL} Shell-sort, http://en.wikipedia.org/wiki/Shell\_sort/

\bibitem{TIME} time man page, http://unixhelp.ed.ac.uk/CGI/man-cgi?time/

\bibitem{FUNCCALL} func\_call\_conv.pdf, http://groups.yahoo.com/group/orga6620/files/

\bibitem{LATEX} Oetiker, Tobias, "The Not So Short Introduction To LaTeX2", http://tobi.oetiker.ch/lshort/

\end{thebibliography}

\end{document}
